/**
*FileContentManager is a Java based file manager desktop application, 
*it can show, edit and manipulate the content of the files archived inside a zip.
*
*Copyright (C) 2007 
*
*Created by Camila Sanchez [http://mimix.wordpress.com/], Rafael Naufal [http://rnaufal.livejournal.com] and Rodrigo [rdomartins@gmail.com]
*
*FileContentManager is free software; you can redistribute it and/or
*modify it under the terms of the GNU Lesser General Public
*License as published by the Free Software Foundation; either
*version 2.1 of the License, or (at your option) any later version.
*
*This library is distributed in the hope that it will be useful,
*but WITHOUT ANY WARRANTY; without even the implied warranty of
*MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
*Lesser General Public License for more details.
*
*You should have received a copy of the GNU Lesser General Public
*License along with FileContentManager; if not, write to the Free Software
*Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
 * Created on 17/07/2006 22:43:04
 */

package br.com.jteam.jfcm.model;

import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

/**
 * <p>
 * Classe que representa uma estrutura de dados do tipo <code>FIFO</code>
 * 
 * @author Rafael Naufal <rafael.naufal@gmail.com>
 * @since 1.0
 * @version $Id$
 */
public class Queue<T> implements Iterable<T>
{
	/**
	 * <p>
	 * Estrutura de fila.
	 */
	private LinkedList<T> queue;

	/**
	 * <p>Contrutor sem argumentos.
	 * 
	 */
	public Queue()
	{
		queue = new LinkedList<T>();
	}

	/**
	 * <p>
	 * Adiciona um elemento na fila.
	 * 
	 * @param element -
	 *            elemento a ser adicionado na fila.
	 * @throws IllegalArgumentException -
	 *             caso o elemento a ser adicionado seja nulo.
	 * @throws IllegalArgumentException -
	 *             caso a fila j&aacute; contenha o elemento a ser inserido.
	 */
	public void add(T element)
	{
		if (element == null)
			throw new IllegalArgumentException(element + " cannot be null.");
		if (contains(element))
			throw new IllegalArgumentException(element + " already present.");
		;
		queue.addLast(element);
	}

	/**
	 * <p>
	 * Verifica se determinado elemento j&aacute; est&aacute; presente na fila.
	 * 
	 * @param element -
	 *            elemento ser verificado quanto &agrave; presen&ccedil;a na fila.
	 * @return <code>true</code> se o elemento j&aacute; estiver presente na
	 *         fila, <code>false</code> em caso contr&aacute;rio. Se o
	 *         elemento for nulo, tamb&eacute;m retorna <code>false</code>.
	 */
	public boolean contains(T element)
	{
		if (element == null)
			return false;
		return queue.contains(element);
	}

	/**
	 * <p>
	 * Verifica se a fila est&aacute; vazia.
	 * 
	 * @return <code>true/code> se a fila estiver vazia, <code>false</code> em caso contr&aacute;rio.
	 */
	public boolean isEmpty()
	{
		return queue.isEmpty();
	}

	/**
	 * <p>
	 * Remove e retorna o elemento da fila. Caso a fila estiver vazia, retorna
	 * <code>null</code>.
	 * 
	 * @return elemento removido da fila.
	 */
	public T remove()
	{
		if (isEmpty())
		{
			return null;
		}
		return queue.removeFirst();
	}

	/**
	 * <p>
	 * Obt&eacute;m o elemento da fila.Caso a fila estiver vazia, retorna
	 * <code>null</code>.
	 * 
	 * @return elemento obtido da fila.
	 */
	public T get()
	{
		if (isEmpty())
		{
			return null;
		}
		return queue.getFirst();
	}

	/**
	 * <p>
	 * Retorna o tamanho da fila.
	 * 
	 * @return tamanho da fila.
	 */
	public int size()
	{
		return queue.size();
	}

	/**
	 * <p>Retorna os elementos da fila em uma lista que n&atilde;o pode ser modificada.
	 * 
	 * @return lista de elementos da fila.
	 * @throws UnsupportedOperationException -
	 *             caso alguma tentativa de modifica&ccedil;&atilde;o da lista seja realizada.
	 */
	public List<T> unmodifiableQueue()
	{
		return Collections.unmodifiableList(queue);
	}

	/**
	 * <p>Contru&ccedil;&atilde;o de um <code>iterator</code> da fila.
	 * 
	 * @return <code>iterator</code> da fila;
	 */
	public Iterator<T> iterator()
	{
		return queue.listIterator();
	}
}
